package serveur;

import java.io.IOException;

public class PlacerNavires implements Runnable{

	private Joueur joueur;

	public PlacerNavires(Joueur joueur) {
		this.joueur = joueur;
	}

	@Override
	public void run() {
		int navireEnCours = 0;
		boolean finPlacement = false;
		do{
			try {

				String message;
				String envoi = Commande.SHIP+
						joueur.getNavires().get(navireEnCours).getLongueur()+
						"/\n";

				joueur.getOut().write(envoi.getBytes());

				System.out.print("Joueur "+joueur.getNom()+ envoi);
				
				message = joueur.getIn().readLine();

				System.out.print("Joueur "+joueur.getNom()+" - Cmd "+message);
				
				//TODO : remettre le test de fin apres verif suppression \0
				/*	if(	message.startsWith(Commande.PUTSHIP) &&
					message.endsWith("/\n")){ 				 */				

				if(	message.startsWith(Commande.PUTSHIP)){

					String[] tabChaines = message.split("/");

					int x1 = Integer.parseInt(tabChaines[1]);
					char y1Char = tabChaines[2].charAt(0);
					int y1 = (int)y1Char - 65;
					//on soustrait 65(A) pour recuperer un indice entre 0 et 15

					//nb points passes en parametres = longueur du navire
					//-1 pour PUTSHIP
					//-1 pour \n 
					//-1 car 2 parametres x et y correspondent a un point
					
					int n = tabChaines.length -3;

					System.out.println(" n = "+n +" - navireEnCours = "+navireEnCours);

					for(int j=1; j<tabChaines.length-1; j++){
						if(j%2==1)
							System.out.print("(x = "+tabChaines[j]);
						else
							System.out.println(", y = "+tabChaines[j]+")" );	
					}


					if((n==1 && 
							(navireEnCours== 0 || navireEnCours== 1))){
						//longueur 1
						
						if((x1 >= 0 && x1 < 16) && (y1 >= 0 && y1 < 16)) {
							if(!joueur.caseOccupee(x1, y1)){
								joueur.getNavires().get(navireEnCours).setxA(x1);
								joueur.getNavires().get(navireEnCours).setyA(y1);
								joueur.getOut().write(Commande.OK.getBytes());
								navireEnCours++;
								
							} else{
								joueur.getOut().write(Commande.WRONG.getBytes());
							}
						}else{
							joueur.getOut().write(Commande.WRONG.getBytes());
						}

					}
					else{
						int x2 = Integer.parseInt(tabChaines[3]);
						char y2Char = tabChaines[4].charAt(0);
						int y2 = (int)y2Char - 65;
						//longueur 2
						if (n == 3  && (navireEnCours==2 || navireEnCours==3)){
							if(	
									valPossible(x1, y1) && 
									valPossible(x2, y2) &&
									sontAlignes(x1, y1, x2, y2)){

								if(		lgValide(2, x1, y1, x2, y2)&&
										!joueur.caseOccupee(x1, y1, x2, y2)){
									joueur.getNavires().get(navireEnCours).setxA(x1);
									joueur.getNavires().get(navireEnCours).setyA(y1);
									joueur.getNavires().get(navireEnCours).setxB(x2);
									joueur.getNavires().get(navireEnCours).setyB(y2);
									joueur.getOut().write(
											Commande.OK.getBytes());
									navireEnCours++;
								} else {
									//case occupee
									joueur.getOut().write(
											Commande.WRONG.getBytes());
								}
							} else{
								//case hors limite
								joueur.getOut().write(
										Commande.WRONG.getBytes());
							}
						}
						else{
							int x3 = Integer.parseInt(tabChaines[5]);
							char y3Char = tabChaines[6].charAt(0);
							int y3 = (int)y3Char - 65;
							//navire de longueur 3
							if(n==5 && (navireEnCours==4||navireEnCours==5)){
								if(	
										valPossible(x1, y1) && 
										valPossible(x2, y2) &&
										valPossible(x3, y3) &&
										sontAlignes(x1, y1, x2, y2, x3, y3)	){
									if(	lgValide(3, x1, y1, x3, y3)&&
											!joueur.caseOccupee(x1,y1,x3,y3)){

										joueur.getNavires().get(navireEnCours).setxA(x1);
										joueur.getNavires().get(navireEnCours).setyA(y1);
										joueur.getNavires().get(navireEnCours).setxB(x3);
										joueur.getNavires().get(navireEnCours).setyB(y3);

										joueur.getOut().write(
												Commande.OK.getBytes());
										navireEnCours++;
									}else{
										//Case deja occupee
										joueur.getOut().write(
												Commande.WRONG.getBytes());
									}
								}else{
									//Case hors limite
									joueur.getOut().write(
											Commande.WRONG.getBytes());
								}
							}else if(n==7 && navireEnCours==6){
								//navire de longueur 4
								int x4 = Integer.parseInt(tabChaines[7]);
								char y4Char = tabChaines[8].charAt(0);
								int y4 = (int)y4Char - 65;

								if(	
										valPossible(x1, y1) && 
										valPossible(x2, y2) &&
										valPossible(x3, y3) &&
										valPossible(x4, y4) &&
										sontAlignes(x1, y1, x2, y2, x3, y3, x4, y4)
										){

									if(lgValide(4, x1, y1, x4, y4) &&
											!joueur.caseOccupee(x1, y1, x4, y4)){
										joueur.getNavires().get(navireEnCours).setxA(x1);
										joueur.getNavires().get(navireEnCours).setyA(y1);
										joueur.getNavires().get(navireEnCours).setxB(x4);
										joueur.getNavires().get(navireEnCours).setyB(y4);
										joueur.getOut().write(
												Commande.OK.getBytes());
										navireEnCours++;
									}else{
										//case occupee
										joueur.getOut().write(
												Commande.WRONG.getBytes());
									}
								} else{
									//case hors limite
									joueur.getOut().write(
											Commande.WRONG.getBytes());
								}
							}
						}
					}

					if(navireEnCours == 7){
						finPlacement=true;
					}

				}else{
					//Commande invalide 
					joueur.getOut().write(Commande.WRONG.getBytes());
				}
			} catch (IOException e) {
				System.err.println("Erreur placement!");
				e.printStackTrace();
			}	

		}while(!finPlacement);
	}

	//renvoie vrai si la distance entre (xA,yA) et (xB,yB) == longueur
	private boolean lgValide(int longueur, int xA, int yA, int xB, int yB){
		if(xA == xB){
			return Math.abs(yB -yA)==(longueur-1);
		}
		else if(yA==yB){
			return Math.abs(xB -xA)==(longueur-1);
		}
		return false;
	}

	//si x et y sont entre 0 et 15 renvoie vrai sinon renvoie faux
	private boolean valPossible(int x, int y){
		if(x>= 0 && x<16 && y>=0 && y>16)
			return true;
		return false;
	}

	private boolean sontAlignes(
			int x1, int y1,
			int x2, int y2, 
			int x3, int y3, int x4, int y4){
		return (x1==x2 && x2==x3 && x3==x4)|| (y1==y2 && y2==y3 && y3==y4); 
	}

	private boolean sontAlignes(
			int x1, int y1,
			int x2, int y2, 
			int x3, int y3){
		return (x1==x2 && x2==x3)|| (y1==y2 && y2==y3); 
	}

	private boolean sontAlignes(int x1, int y1,int x2, int y2){
		return (x1==x2)|| (y1==y2); 
	}
}